﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Simple.Framework.Configuration;
using Simple.Framework.Ioc;
using Simple.Framework.Load;
using Simple.Framework.Logger;
using Simple.Framework.Protocol;
using Simple.Framework.Schedule;
using Simple.Tools;
using SimpleNet.Handle;
using SimpleNet.Pipeline;
using SimpleNet.Protocol;

/*********************************************************
 * 命名空间 Simple.BasicNet.Core.Net
 * 接口名称 Host
 * 开发人员：11920
 * 创建时间：2023/4/6 15:33:15
 * 描述说明：
 * 更改历史：
 * 
 * *******************************************************/
namespace SimpleNet
{
    public class Host: IHost
	{
		IContainer container;
        IConfiguration configution;
		ILogger<Host> logger;

		IClassLoader classLader;
		List<IPretty>  prettyCores { get; set; }
		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
        public static IHost BuilderHost()
		{
			return new Host();
		}
		/// <summary>
		/// 启动任务启动服务器
		/// </summary>
		/// <returns></returns>
		public IHost Start()
		{
			logger = container.GetService<ILogger<Host>>();
			classLader.LoadClass();
			var scheduleManager = container.GetService<IScheduleManager>();
			scheduleManager.Start();
			prettyCores = container.GetServiceAll<IPretty>().ToList();
			foreach (var prettyCore in prettyCores)
			{
				prettyCore.Start();
			}
			return this;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="ConfigurationPath"></param>
		/// <returns></returns>
		public IHost SetConfiguration(string ConfigurationPath) 
		{
			Configuration.SetConfiguration(ConfigurationPath);
			return this;

		}
		/// <summary>
		/// 替换容器之后需要重新注册
		/// </summary>
		/// <returns></returns>
		public IHost ReplaceContainer(IContainer container)
		{
			this.container = Container.SetContainer(container);
			Initalization();
			return this;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="action"></param>
		/// <returns></returns>
		/// <exception cref="ArgumentNullException"></exception>
		public IHost Regster(Action<IContainer> action)
		{
			if (action==null)
			{
				throw new ArgumentNullException(nameof(action));
			}
			action.Invoke(container);
			return this;
		}
		
		/// <summary>
		/// 
		/// </summary>
		/// <typeparam name="TMessageHandle"></typeparam>
		/// <returns></returns>
		public IHost ConfigutionMessageHandle<TMessageHandle>() where TMessageHandle : IMessageHandle
		{   
			container.RegisterSingleton<IMessageHandle,TMessageHandle>().Autowird();
			return this;
		}

		public IHost ConfigutionLogger(Action<ClassNameLoggerProvider> action)
		{
			if (action!=null)
			{
				ClassNameLoggerProvider provider = (ClassNameLoggerProvider)container.GetService<ILoggerProvider>();
				action.Invoke(provider);
			}
			return this;
		}

		
		/// <summary>
		/// 
		/// </summary>
		private Host()
		{
			container = Container.GetContainer();
			Initalization();
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="container"></param>
		/// <returns></returns>
		private void Initalization()
		{
			container.RegistSingletonInstance<ILoggerProvider, ClassNameLoggerProvider>(new ClassNameLoggerProvider(string.Empty));
			//ILoggerProvider provider = container.GetService<ILoggerProvider>();
			logger = container.GetService<ILogger<Host>>();
			container.Register<IContext,Context>().Autowird();
			container.Register<ISimpleJobject, SimpleJObject>().Autowird();

			container.RegisterSingleton<IConfiguration,Configuration>();

			configution = container.GetService<IConfiguration>();

			#region  socket 消息处理
			container.RegisterSingleton<IMessageHandle,MessageHandle>().Autowird();
			#endregion

			#region socket 客户端管理
			container.RegisterSingleton<IClientManager,ClientManager>().Autowird();
			#endregion

			#region 任务管理
			container.RegisterSingleton<IScheduleManager,ScheduleManager>().Autowird();
			#endregion

			#region socket 监听
			container.RegisterSingleton<IPretty,Pretty>().Autowird();
			#endregion

			#region
			container.Register<IScheduleHandle,ScheduleHandle>().Autowird();
			#endregion

			container.Register<IConnection,Connection>().Autowird();
			container.RegisterSingleton<IClassLoader, ClassLoader>().Autowird();
			classLader = container.GetService<IClassLoader>();

			RegisterClassLoadProcess<LoadClassLoadProcess>();

			container.RegisterSingleton<IMDTDataPackProtocol,MDTDataPackProtocol>();

			logger.LogError("Initalization successfully!");
		}


		public void RegisterClassLoadProcess<TIClassLoadProcess>()where TIClassLoadProcess : IClassLoadProcess
		{
			container.Register<TIClassLoadProcess>().Autowird();
			var load=container.GetService<TIClassLoadProcess>();
			classLader.Register(load);
		}

		public T GetService<T>()
		{
			return container.GetService<T>();
		}

		IContainer IHost.GetContainer()
		{
			return this.container;
		}
	}
}
